package com.ruoyi.common.utils;

import lombok.extern.slf4j.Slf4j;
import org.bouncycastle.jce.provider.BouncyCastleProvider;

import javax.crypto.Mac;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.security.Security;
import java.util.Base64;

@Slf4j
public class SignatureUtils {


    static {
        Security.addProvider(new BouncyCastleProvider());
    }

    private static final String HMAC_SM3_ALGORITHM = "HmacSM3";
    private static final String KEY = "abcdefg123hijklmnopqrstuvwxyz";


    /**
     * 签名
     * @param data
     * @return
     * @throws Exception
     */
    public static String createSignature(Object data){
        try {
            SecretKey secretKey = new SecretKeySpec(KEY.getBytes(), HMAC_SM3_ALGORITHM);
            Mac mac = Mac.getInstance(HMAC_SM3_ALGORITHM, "BC");
            mac.init(secretKey);
            String sign = Base64.getEncoder().encodeToString(mac.doFinal(data.toString().getBytes()));
            log.info("签名 ===> 原文：{}，签名结果:{}",data,sign);
            return sign;
        } catch (Exception e) {
            log.error("签名失败,{}",e.getMessage());
            return "";
        }
    }

    /**
     * 验签
     * @param data
     * @param sign
     * @return
     * @throws Exception
     */
    public static boolean verifySignature(Object data, String sign){

        boolean result = false;
        try {
            String generatedSign = createSignature(data.toString().getBytes(), KEY.getBytes());
            result = generatedSign.equals(sign);
            log.info("验签结果：【{}】 ===> 原文：{},签名值：{}",result,data,sign);
            return result;
        } catch (Exception e) {
            log.error("验签失败,{}",e.getMessage());
            return false;
        }
    }

    /**
     * 生成HMAC-SM3签名
     * @param data 需要签名的数据
     * @param key 密钥
     * @return 签名结果
     */
    public static String createSignature(byte[] data, byte[] key) throws Exception {
        SecretKey secretKey = new SecretKeySpec(key, HMAC_SM3_ALGORITHM);
        Mac mac = Mac.getInstance(HMAC_SM3_ALGORITHM, "BC");
        mac.init(secretKey);
        return Base64.getEncoder().encodeToString(mac.doFinal(data));
    }

    /**
     * 验证HMAC-SM3签名
     * @param data 原始数据
     * @param key 密钥
     * @param sign 签名值
     * @return 验签结果
     */
    public static boolean verifySignature(byte[] data, byte[] key, String sign) throws Exception {
        String generatedSign = createSignature(data, key);
        return generatedSign.equals(sign);
    }
}
